package com.youpai.platform.user.service.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.youpai.platform.common.enums.ProcessCodeEnum;
import com.youpai.platform.common.exceptions.BaseBizException;
import com.youpai.platform.user.service.entity.po.UserFollowPO;
import com.youpai.platform.user.service.entity.po.UserPO;
import com.youpai.platform.user.service.mapper.UserFollowMapper;
import com.youpai.platform.user.service.mapper.UserMapper;
import com.youpai.platform.user.service.service.UserFollowService;
import com.youpai.platform.user.web.entity.dto.UserFollowDTO;
import com.youpai.platform.user.web.entity.req.UserFollowListReq;
import com.youpai.platform.user.web.entity.req.UserFollowReq;
import com.youpai.platform.user.web.entity.resp.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 用户关注Service
 * @Author:welles
 * @Date:2022/7/23
 */
@Slf4j
@Service
public class UserFollowServiceImpl implements UserFollowService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserFollowMapper userFollowMapper;

    @Override
    public UserResp followUser(UserFollowReq req) {
        //1. 判断用户和被关注用户是否存在
        LambdaQueryWrapper<UserPO> userFollowPOQueryWrapper = new LambdaQueryWrapper<>();
        userFollowPOQueryWrapper
                .eq(UserPO::getUid, req.getUid());
        UserPO userFollowPO = userMapper.selectOne(userFollowPOQueryWrapper);
        if(userFollowPO == null){
            log.error("关注用户不存在！");
            throw new BaseBizException(ProcessCodeEnum.USER_NOT_EXIST);
        }
        LambdaQueryWrapper<UserPO> userBeFollowPOQueryWrapper = new LambdaQueryWrapper<>();
        userBeFollowPOQueryWrapper
                .eq(UserPO::getUid, req.getUid());
        UserPO userBeFollowPO = userMapper.selectOne(userBeFollowPOQueryWrapper);
        if(userBeFollowPO == null){
            log.error("被关注用户不存在！");
            throw new BaseBizException(ProcessCodeEnum.USER_NOT_EXIST);
        }
        //关注
        if(req.getFollowStatus() == 1){
            //判断当前关注条件是否存在
            LambdaQueryWrapper<UserFollowPO> userFollowQueryWrapper = new LambdaQueryWrapper<>();
            userFollowQueryWrapper
                    .eq(UserFollowPO::getFollowUid, req.getUid())
                    .eq(UserFollowPO::getBeFollowUid, req.getBeUid());
            UserFollowPO userFollowTo = userFollowMapper.selectOne(userFollowQueryWrapper);
            if(userFollowTo != null){
                log.error("已关注当前用户！");
                throw new BaseBizException(ProcessCodeEnum.USER_FOLLOW_EXISTENCE);
            }
            UserFollowPO userFollow = new UserFollowPO();
            userFollow.setFollowUid(Long.valueOf(req.getUid()));
            userFollow.setBeFollowUid(Long.valueOf(req.getBeUid()));
            userFollow.setCreateTime(getNow());
            userFollow.setUpdateTime(getNow());
            int count = userFollowMapper.insert(userFollow);
            if(count > 0){
                //关注成功
                return new UserResp().setHintText("成功关注");
            }else {
                log.error("关注用户失败！");
                throw new BaseBizException(ProcessCodeEnum.USER_FOLLOW_FAILED);
            }
        }else {
            //取消关注逻辑
            LambdaQueryWrapper<UserFollowPO> userFollowQueryWrapper = new LambdaQueryWrapper<>();
            userFollowQueryWrapper
                    .eq(UserFollowPO::getFollowUid, req.getUid())
                    .eq(UserFollowPO::getBeFollowUid, req.getBeUid());
            int count = userFollowMapper.delete(userFollowQueryWrapper);
            if (count > 0) {
                return new UserResp().setHintText("成功取消关注");
            } else {
                log.error("取消关注用户失败！");
                throw new BaseBizException(ProcessCodeEnum.USER_FOLLOW_FAILED);
            }
        }
    }

    //获取关注列表
    @Override
    public List<UserFollowDTO> getFollowUserList(UserFollowListReq req) {
        List<UserFollowDTO> userFollowDTOS = new ArrayList<>();
        LambdaQueryWrapper<UserFollowPO> userFollowPOQueryWrapper = new LambdaQueryWrapper<>();
        userFollowPOQueryWrapper
                .eq(UserFollowPO::getFollowUid, req.getUid());
        List<UserFollowPO> userFollowPOList = userFollowMapper.selectList(userFollowPOQueryWrapper);
        if(!CollectionUtils.isEmpty(userFollowPOList)) {
            List<Long> beFollowUidList =
                    userFollowPOList.stream().map(UserFollowPO::getBeFollowUid).collect(Collectors.toList());
            List<UserPO> userPOS = userMapper.getUserFollowByUid(beFollowUidList);
            for (UserPO userPO : userPOS) {
                UserFollowDTO userFollowDTO = new UserFollowDTO(userPO);
                userFollowDTOS.add(userFollowDTO);
            }
        }
        return userFollowDTOS;
    }

    //获取粉丝
    @Override
    public List<UserFollowDTO> getBeFollowUserList(UserFollowListReq req) {
        List<UserFollowDTO> userFollowDTOS = new ArrayList<>();
        LambdaQueryWrapper<UserFollowPO> userFollowPOQueryWrapper = new LambdaQueryWrapper<>();
        userFollowPOQueryWrapper
                .eq(UserFollowPO::getBeFollowUid, req.getUid());
        List<UserFollowPO> userFollowPOList = userFollowMapper.selectList(userFollowPOQueryWrapper);
        if(!CollectionUtils.isEmpty(userFollowPOList)) {
            List<Long> followUidList =
                    userFollowPOList.stream().map(UserFollowPO::getFollowUid).collect(Collectors.toList());
            List<UserPO> userPOS = userMapper.getUserFollowByUid(followUidList);
            for (UserPO userPO : userPOS) {
                UserFollowDTO userFollowDTO = new UserFollowDTO(userPO);
                userFollowDTOS.add(userFollowDTO);
            }
        }
        return userFollowDTOS;
    }

    public static Timestamp getNow() {
        return new Timestamp(System.currentTimeMillis());
    }
}
